package com.zcyppyh.ddns.utils;

import com.aliyun.alidns20150109.Client;
import com.aliyun.teaopenapi.models.Config;
import com.zcyppyh.ddns.config.AliAccess;
import com.zcyppyh.ddns.config.ConfigFile;
import com.zcyppyh.ddns.config.ProjectConfig;
import com.zcyppyh.ddns.config.Record;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.File;
import java.util.ArrayList;
import java.util.List;

/**
 * @author: zcyppyh
 * @time: 2023/8/16 16:49
 * @version: 1
 * @desc:
 */
public class ProjectUtil {

    private static final String ENDPOINT = "alidns.cn-hangzhou.aliyuncs.com";
    private static final String MODE_ENV = "env";
    private static final String MODE_PROP = "prop";
    private static final String ENV_ACCESS_KEY_ID = "ALIBABA_CLOUD_ACCESS_KEY_ID";
    private static final String ENV_ACCESS_KEY_SECRET = "ALIBABA_CLOUD_ACCESS_KEY_SECRET";

    private static ProjectConfig PROJECT_CONFIG;
    private static Client WHOLE_CLIENT;

    public static Client createClient() throws Exception {
        return createClient( false);
    }

    public static Client createClient(boolean froceFlush) throws Exception {
        if(froceFlush || WHOLE_CLIENT==null){
            setProp();
            Config config = new Config().setAccessKeyId(PROJECT_CONFIG.getAliAccess().getId())
                    .setAccessKeySecret(PROJECT_CONFIG.getAliAccess().getSecret()).setEndpoint(ENDPOINT);
            WHOLE_CLIENT = new Client(config);
        }
        return WHOLE_CLIENT;
    }

    public static ProjectConfig getProjectConfig(){
        return PROJECT_CONFIG;
    }

    public static ProjectConfig getProjectConfig(boolean froceFlush) throws Exception {
        if(froceFlush){
            setProp();
        }
        return PROJECT_CONFIG;
    }

    static {
        try {
            setProp();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private static void setProp() throws Exception {
        if(PROJECT_CONFIG == null){
            PROJECT_CONFIG = new ProjectConfig();
        }
        ConfigFile bean = SpringBeanUtil.getBean(ConfigFile.class);
        String configFileName = bean.getProject();

        String projectPath = System.getProperty("user.dir");
        projectPath = projectPath.substring(0, projectPath.lastIndexOf(File.separator));
        File configFile = new File(projectPath + File.separator + configFileName);
        if(!configFile.exists()){
            throw new Exception("配置文件有误");
        }

        DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
        DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
        Document document = documentBuilder.parse(configFile);
        NodeList name = document.getElementsByTagName("name");
        String domainName = name.item(0).getFirstChild().getNodeValue();
        PROJECT_CONFIG.setDomain(domainName);

        NodeList recordsNodeList = document.getElementsByTagName("records");
        if(recordsNodeList == null || recordsNodeList.getLength() == 0){
            throw new Exception("配置文件有误");
        }

        Element recordsEle = (Element) recordsNodeList.item(0);
        NodeList nodeList = recordsEle.getElementsByTagName("record");

        List<Record> recordList = new ArrayList<Record>();
        for (int i = 0; i < nodeList.getLength(); i++) {
            Element element = (Element) nodeList.item(i);
            Record record = new Record();
            String host = element.getElementsByTagName("host").item(0).getFirstChild().getNodeValue();
            String type = element.getElementsByTagName("type").item(0).getFirstChild().getNodeValue();
            record.setRR(host);
            record.setType(type);
            recordList.add(record);
        }
        PROJECT_CONFIG.setRecordList(recordList);

        NodeList cronsNodeList = document.getElementsByTagName("crons");
        if(cronsNodeList == null || cronsNodeList.getLength() == 0){
            throw new Exception("配置文件有误");
        }

        Element cronsEle = (Element) cronsNodeList.item(0);
        NodeList cronNodeList = cronsEle.getElementsByTagName("cron");
        if(cronNodeList != null && cronNodeList.getLength()>0){
            List<String> cronList = new ArrayList();
            for(int i=0; i<cronNodeList.getLength(); i++){
                String cron = cronNodeList.item(i).getFirstChild().getNodeValue();
                cronList.add(cron);
            }
            PROJECT_CONFIG.setCronList(cronList);
        }

        NodeList accessNodeList = document.getElementsByTagName("access");
        if(accessNodeList == null || accessNodeList.getLength() == 0){
            throw new Exception("配置文件有误");
        }

        Element accessEle = (Element) accessNodeList.item(0);
        String mode = accessEle.getElementsByTagName("mode").item(0).getFirstChild().getNodeValue();
        AliAccess aliAccess = new AliAccess();
        if(MODE_PROP.equals(mode)){
            NodeList keyNode = accessEle.getElementsByTagName("key");
            if(keyNode != null && keyNode.getLength()>0){
                String key = keyNode.item(0).getFirstChild().getNodeValue();
                aliAccess.setId(key);
            }
            NodeList secretNode = accessEle.getElementsByTagName("secret");
            if(secretNode != null && secretNode.getLength()>0){
                String secret = secretNode.item(0).getFirstChild().getNodeValue();
                aliAccess.setSecret(secret);
            }
        }else if(MODE_ENV.equals(mode)){
            aliAccess.setId(System.getenv(ENV_ACCESS_KEY_ID));
            aliAccess.setSecret(System.getenv(ENV_ACCESS_KEY_SECRET));
        }
        PROJECT_CONFIG.setAliAccess(aliAccess);
    }

}
